package com.iwhalecloud.citybrain.flow.platform.manager.application.service.impl.subprocess;

import java.util.Objects;

import com.fasterxml.jackson.databind.JsonNode;
import com.iwhalecloud.citybrain.flow.platform.manager.application.common.context.FlowElementProcessContext;
import com.iwhalecloud.citybrain.flow.platform.manager.application.service.SubProcessActivityProcessor;
import com.iwhalecloud.citybrain.flow.platform.manager.domain.enums.MultiInstanceKeyEnum;
import com.iwhalecloud.citybrain.flow.platform.manager.domain.model.CompletionCondition;
import com.iwhalecloud.citybrain.flow.platform.manager.domain.model.OneVoteVetoType;
import org.flowable.bpmn.model.FlowableListener;
import org.flowable.bpmn.model.ImplementationType;
import org.flowable.bpmn.model.SubProcess;
import org.flowable.engine.delegate.BaseExecutionListener;
import org.springframework.stereotype.Service;

/**
 * @author lich
 * @date 2021/10/31 11:19
 */
@Service
public class MultiInstanceSubProcessActivityProcessor implements SubProcessActivityProcessor {

    @Override
    public boolean support(SubProcess subProcess) {
        return subProcess.hasMultiInstanceLoopCharacteristics();
    }

    @Override
    public void process(FlowElementProcessContext context) {
        SubProcess subProcess = (SubProcess) context.getActivity();

        resolveSubProcessListener(subProcess);

        resolveOneVoteVeto(context);

        resolveSignCompleteHandler(subProcess,context);
    }

    private void resolveOneVoteVeto(FlowElementProcessContext context) {
        JsonNode jsonNode = context.getElementNode();
        JsonNode properties = jsonNode.get("properties");
        if (Objects.nonNull(properties)){
            JsonNode oneVoteVetoTypeJsonNode = properties.get(MultiInstanceKeyEnum.ONE_VOTE_VETO_TYPE.getCode());
            if (Objects.nonNull(oneVoteVetoTypeJsonNode)){
                String oneVoteVetoTypeValue = oneVoteVetoTypeJsonNode.toString();
                OneVoteVetoType oneVoteVetoType = new OneVoteVetoType();
                oneVoteVetoType.setDeploymentId(context.getDeployId());
                oneVoteVetoType.setNodeCode(context.getNodeCode());
                oneVoteVetoType.setValue(oneVoteVetoTypeValue);
                oneVoteVetoType.save();
            }
        }
    }


    private void resolveSignCompleteHandler(SubProcess subProcess,FlowElementProcessContext context) {
        String completionConditionStr = subProcess.getLoopCharacteristics().getCompletionCondition();
        //保存节点完成情况表达式
        //默认
        CompletionCondition completionCondition = new CompletionCondition();
        completionCondition.setDeploymentId(context.getDeployId());
        completionCondition.setNodeCode(context.getNodeCode());
        completionCondition.setValue(completionConditionStr);
        completionCondition.save();
        subProcess.getLoopCharacteristics().setCompletionCondition("${multiInstanceCompleteHandler.accessCondition(execution)}");
    }


    private void resolveSubProcessListener(SubProcess subProcess) {
        resolveSubProcessListener(subProcess, BaseExecutionListener.EVENTNAME_END, MultiInstanceSubProcessCompleteListener.class.getCanonicalName());
    }

    private void resolveSubProcessListener(SubProcess subProcess, String event, String implement) {
        FlowableListener completeListener = new FlowableListener();
        completeListener.setEvent(event);
        completeListener.setImplementationType(ImplementationType.IMPLEMENTATION_TYPE_CLASS);
        completeListener.setImplementation(implement);
        subProcess.getExecutionListeners().add(completeListener);
    }
}
